home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / sox / sound2sun.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  6KB  |  202 lines

  1. /************************************************************************/
  2. /*      Copyright 1989 by Rich Gopstein and Harris Corporation          */
  3. /*                                                                      */
  4. /*      Permission to use, copy, modify, and distribute this software   */
  5. /*      and its documentation for any purpose and without fee is        */
  6. /*      hereby granted, provided that the above copyright notice        */
  7. /*      appears in all copies and that both that copyright notice and   */
  8. /*      this permission notice appear in supporting documentation, and  */
  9. /*      that the name of Rich Gopstein and Harris Corporation not be    */
  10. /*      used in advertising or publicity pertaining to distribution     */
  11. /*      of the software without specific, written prior permission.     */
  12. /*      Rich Gopstein and Harris Corporation make no representations    */
  13. /*      about the suitability of this software for any purpose.  It     */
  14. /*      provided "as is" without express or implied warranty.           */
  15. /************************************************************************/
  16.  
  17. /************************************************************************/
  18. /* sound2sun.c - Convert sampled audio files into uLAW format for the   */
  19. /*               Sparcstation 1.                                        */
  20. /*               Send comments to ..!rutgers!soleil!gopstein            */
  21. /************************************************************************/
  22. /*                                    */
  23. /*  Modified November 27, 1989 to convert to 8000 samples/sec           */
  24. /*   (contrary to man page)                                             */
  25. /*  Modified December 13, 1992 to write standard Sun .au header with    */
  26. /*   unspecified length.  Also made miscellaneous changes for         */
  27. /*   VMS port.  (K. S. Kubo, ken@hmcvax.claremont.edu)            */
  28. /*  Fixed Bug with converting slow sample speeds            */
  29. /*                                    */
  30. /************************************************************************/
  31.  
  32.  
  33. #include <stdio.h>
  34.  
  35. #define DEFAULT_FREQUENCY 11000
  36.  
  37. #ifdef VAXC
  38. #define    READ_OPEN    "r", "mbf=16", "shr=get"
  39. #define WR_OPEN        "w", "mbf=16"
  40. #else
  41. #define READ_OPEN    "r"
  42. #define WR_OPEN        "w"
  43. #endif
  44.  
  45. FILE *infile, *outfile;
  46.  
  47. /* convert two's complement ch into uLAW format */
  48.  
  49. unsigned int cvt(ch)
  50. int ch;
  51. {
  52.  
  53.   int mask;
  54.  
  55.   if (ch < 0) {
  56.     ch = -ch;
  57.     mask = 0x7f;
  58.   } else {
  59.     mask = 0xff;
  60.   }
  61.  
  62.   if (ch < 32) {
  63.     ch = 0xF0 | 15 - (ch / 2);
  64.   } else if (ch < 96) {
  65.     ch = 0xE0 | 15 - (ch - 32) / 4;
  66.   } else if (ch < 224) {
  67.     ch = 0xD0 | 15 - (ch - 96) / 8;
  68.   } else if (ch < 480) {
  69.     ch = 0xC0 | 15 - (ch - 224) / 16;
  70.   } else if (ch < 992) {
  71.     ch = 0xB0 | 15 - (ch - 480) / 32;
  72.   } else if (ch < 2016) {
  73.     ch = 0xA0 | 15 - (ch - 992) / 64;
  74.   } else if (ch < 4064) {
  75.     ch = 0x90 | 15 - (ch - 2016) / 128;
  76.   } else if (ch < 8160) {
  77.     ch = 0x80 | 15 - (ch - 4064) /  256;
  78.   } else {
  79.     ch = 0x80;
  80.   }
  81. return (mask & ch);
  82. }
  83.  
  84. /* write a "standard" sun header with an unspecified length */
  85. #define wrulong(fp, ul) putc((ul >> 24) & 0xff, fp); \
  86.     putc((ul >> 16) & 0xff, fp); putc((ul >> 8) & 0xff, fp); \
  87.     putc(ul & 0xff, fp);
  88.  
  89. static void
  90. wr_header(optr)
  91. FILE *optr;
  92. {
  93.     wrulong(optr, 0x2e736e64);    /* Sun magic */
  94.     wrulong(optr, 24);        /* header size in bytes */
  95.     wrulong(optr, ((unsigned)(~0)));    /* unspecified data size */
  96.     wrulong(optr, 1);        /* Sun uLaw format */
  97.     wrulong(optr, 8000);    /* sample rate by definition :-) */
  98.     wrulong(optr, 1);        /* single channel */
  99. }
  100.  
  101. /*******************************************************
  102. /*                                                     */
  103. /* Usage is "sound2sun [-f frequency] infile outfile"  */
  104. /*                                                     */
  105. /* "frequency" is the samples per second of the infile */
  106. /* the outfile is always 8000 samples per second.      */
  107. /*                                                     */
  108. /*******************************************************/
  109.  
  110. /***********************************************************************/
  111. /*                                                                     */
  112. /* The input file is expected to be a stream of one-byte excess-128    */
  113. /* samples.  Each sample is converted to 2's complement by subtracting */
  114. /* 128, then converted to uLAW and output.  We calculate the proper    */
  115. /* number of input bytes to skip in order to make the sample frequency */
  116. /* convert to 8000/sec properly.  Interpolation could be added, but it */
  117. /* doesn't appear to be necessary.                                     */
  118. /*                                                                     */
  119. /***********************************************************************/
  120.  
  121.  
  122. main(argc, argv)
  123. int argc;
  124. char *argv[];
  125. {
  126.  
  127.   float sum = 0;
  128.   float frequency, increment;
  129.  
  130.   unsigned char ch;
  131.   unsigned char ulaw;
  132.  
  133.   int chr;
  134.  
  135.   if ((argc != 3) && (argc != 5)) {
  136.     fprintf(stderr,"Usage: sound2sun [-f frequency] infile outfile\n");
  137.     exit(1);
  138.   }
  139.  
  140.   if (argc == 5) {
  141.     if (strcmp(argv[1], "-f") != 0) {
  142.       fprintf(stderr, "Usage: sound2sun [-f frequency] infile outfile\n");
  143.       exit(1);
  144.     } else {
  145.       frequency = atoi(argv[2]);
  146.     }
  147.   } else {
  148.     frequency = DEFAULT_FREQUENCY;
  149.   }
  150.  
  151.   if ((infile = fopen(argv[argc-2], READ_OPEN)) == NULL) {
  152.     perror("Error opening infile");
  153.     exit(0);
  154.   }
  155.  
  156.   if ((outfile = fopen(argv[argc-1], WR_OPEN)) == NULL) {
  157.     perror("Error opening outfile");
  158.     exit(0);
  159.   }
  160.  
  161.   wr_header(outfile);
  162.  
  163.   /* increment is the number of bytes to read each time */
  164.  
  165.   increment = frequency / 8000;
  166.  
  167.   ch = fgetc(infile);
  168.  
  169.   while (!feof(infile)) {
  170.  
  171.     /* convert the excess 128 to two's complement */
  172.  
  173.     chr = 0x80 - ch;
  174.  
  175.     /* increase the volume */
  176.     /* convert to uLAW */
  177.  
  178.     ulaw = cvt(chr * 16);
  179.  
  180.     /* output it */
  181.  
  182.     fputc((char) ulaw, outfile);
  183.  
  184.     /* skip enough input bytes to compensate for sampling frequency diff */
  185.  
  186.     sum += increment;
  187.  
  188.     while(sum > 0) {
  189.       if (!feof(infile)) ch = fgetc(infile);
  190.       sum--;
  191.     }
  192.  
  193.   }
  194.  
  195.   fclose(infile);
  196.   fclose(outfile);
  197. }
  198.  
  199. /*  DEC/CMS REPLACEMENT HISTORY, Element SOUND2SUN.C */
  200. /*  *1    14-DEC-1992 17:46:37 CENYDD "main program" */
  201. /*  DEC/CMS REPLACEMENT HISTORY, Element SOUND2SUN.C */
  202.